home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / packet / p_aa4re / bb212src / bbstr.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-12-15  |  13.4 KB  |  513 lines

  1. (*===========================================================================*)
  2. (* String service routines                                                   *)
  3. (*                                                                           *)
  4. (*   Copyright 1988, 1989 by H. Roy Engehausen.  All rights reserved.        *)
  5. (*                                                                           *)
  6. (*===========================================================================*)
  7.  
  8. {$R-}
  9.  
  10. UNIT BBSTR;
  11.  
  12. INTERFACE
  13.  
  14. USES
  15.   bbdummy;
  16.  
  17. FUNCTION  w2c            (    inw        : WORD  ) : str5;
  18. FUNCTION  substr         (VAR instr      : STRING;
  19.                               start_chr  : BYTE;
  20.                               length_chr : BYTE)   : STRING;
  21. FUNCTION  subword        (    instr      : str_ptr;
  22.                               inpoint    : BYTE;
  23.                               incnt      : BYTE)   : STRING;
  24. FUNCTION  subwordl       (VAR instr      : STRING;
  25.                               inpoint    : BYTE;
  26.                               incnt      : BYTE)   : STRING;
  27. FUNCTION  words          (VAR instr      : STRING) : BYTE;
  28. FUNCTION  strip          (VAR instr      : STRING;
  29.                               st_type    : CHAR)   : STRING;
  30. PROCEDURE strip_var      (VAR instr      : STRING;
  31.                               st_type    : CHAR);
  32. PROCEDURE strip_crlf     (VAR instr      : STRING);
  33. FUNCTION  left           (    instr      : STRING;
  34.                               length_chr : BYTE)   : STRING;
  35. PROCEDURE upcase_str_var (VAR instr      : STRING);
  36. FUNCTION  upcase_str     (    instr      : STRING) : STRING;
  37. FUNCTION  find           (    haystack   : str_ptr;
  38.                               needle     : str_ptr) : BYTE;
  39. FUNCTION  substr_compare (VAR instr      : STRING;
  40.                               start_chr  : BYTE;
  41.                               compare_str: STRING)  : BOOLEAN;
  42.  
  43. IMPLEMENTATION
  44.  
  45. USES
  46.   bbstack;
  47.  
  48. {$DEFINE DEPTH}
  49.  
  50. {$I ASCII.PAS}
  51.  
  52. (*===========================================================================*)
  53. (* Convert a word to a decimal number                                        *)
  54. (*===========================================================================*)
  55.  
  56. FUNCTION w2c(inw : WORD) : str5;
  57.   VAR
  58.     out : str5;
  59.  
  60.   BEGIN;
  61.  
  62.     STR(inw, out);
  63.     w2c := out;
  64.  
  65.   END;
  66.  
  67. (*===========================================================================*)
  68. (* Substring a string.  LENGTH_CHR = 0 means the rest of the string          *)
  69. (*    Contrary to the declartion, instr is not VAR.  Thats just to produce   *)
  70. (*    nicer code                                                             *)
  71. (*===========================================================================*)
  72.  
  73. FUNCTION  substr(VAR instr      : STRING;
  74.                      start_chr  : BYTE;
  75.                      length_chr : BYTE) : STRING;
  76.  
  77.   BEGIN;
  78.  
  79. {$IFDEF DEPTH}
  80. stack_depth;
  81. {$ENDIF}
  82.  
  83.     IF length_chr = 0 THEN
  84.       length_chr := 255;
  85.  
  86.     substr := COPY(instr, start_chr, length_chr);
  87.  
  88.   END;
  89.  
  90. (*===========================================================================*)
  91. (* Subword a string.  INCNT = 0 means the rest of the string                 *)
  92. (*    Contrary to the declartion, instr is not VAR.  Thats just to produce   *)
  93. (*    nicer code                                                             *)
  94. (*===========================================================================*)
  95.  
  96. FUNCTION subword(instr : str_ptr; inpoint : BYTE; incnt : BYTE) : STRING;
  97.  
  98.   VAR
  99.     chr_ptr    : BYTE;
  100.     in_l       : BYTE;
  101.     word_start : BYTE;
  102.     word_cnt   : BYTE;
  103.     word_end   : BYTE;
  104.     out_str    : STRING;
  105.  
  106.   BEGIN;
  107.  
  108. {$IFDEF DEPTH}
  109. stack_depth;
  110. {$ENDIF}
  111.  
  112.     word_cnt := 0;
  113.     chr_ptr  := 0;
  114.     out_str  := '';
  115.     in_l     := LENGTH(instr^);
  116.  
  117.     IF incnt = 0 THEN
  118.       incnt := in_l;
  119.  
  120.     WHILE (word_cnt < (inpoint + incnt - 1))
  121.                          AND (chr_ptr < in_l) DO
  122.       BEGIN;
  123.  
  124.         WHILE (chr_ptr < in_l) AND (instr^[chr_ptr+1] = ' ') DO
  125.           INC(chr_ptr);
  126.  
  127.         word_start := chr_ptr + 1;
  128.  
  129.         WHILE (chr_ptr < in_l) AND (instr^[chr_ptr+1] <> ' ') DO
  130.           INC(chr_ptr);
  131.  
  132.         word_end := chr_ptr;
  133.  
  134.         INC(word_cnt);
  135.  
  136.         IF word_cnt >= inpoint THEN
  137.           BEGIN;
  138.             IF word_start <= word_end THEN
  139.               IF LENGTH(out_str) > 0 THEN
  140.                 out_str := out_str + ' ' +
  141.                   COPY(instr^, word_start, word_end-word_start+1)
  142.               ELSE
  143.                 out_str := COPY(instr^, word_start, word_end-word_start+1);
  144.           END;
  145.  
  146.       END;
  147.  
  148.     subword := out_str;
  149.  
  150.   END;
  151.  
  152. (*===========================================================================*)
  153. (* Subword a string.  INCNT = max number of characters to output             *)
  154. (*    Contrary to the declartion, instr is not VAR.  Thats just to produce   *)
  155. (*    nicer code                                                             *)
  156. (*===========================================================================*)
  157.  
  158. FUNCTION subwordl(VAR instr : STRING; inpoint : BYTE; incnt : BYTE) : STRING;
  159.  
  160.   VAR
  161.     chr_ptr    : BYTE;
  162.     word_start : BYTE;
  163.     word_cnt   : BYTE;
  164.     word_end   : BYTE;
  165.     out_cnt    : BYTE;
  166.  
  167.   BEGIN;
  168.  
  169.     word_cnt := 0;
  170.     chr_ptr  := 0;
  171.  
  172.     WHILE (word_cnt < inpoint) AND (chr_ptr < LENGTH(instr)) DO
  173.       BEGIN;
  174.  
  175.         WHILE (chr_ptr < LENGTH(instr)) AND (instr[chr_ptr+1] = ' ') DO
  176.           INC(chr_ptr);
  177.  
  178.         word_start := chr_ptr + 1;
  179.  
  180.         WHILE (chr_ptr < LENGTH(instr)) AND (instr[chr_ptr+1] <> ' ') DO
  181.           INC(chr_ptr);
  182.  
  183.         word_end := chr_ptr;
  184.  
  185.         INC(word_cnt);
  186.  
  187.         IF word_cnt >= inpoint THEN
  188.           BEGIN;
  189.             out_cnt := word_end - word_start+1;
  190.             IF out_cnt > incnt THEN
  191.               out_cnt := incnt;
  192.  
  193.             subwordl := COPY(instr, word_start, out_cnt);
  194.             EXIT;
  195.           END;
  196.  
  197.       END;
  198.  
  199.     subwordl := '';
  200.  
  201.   END;
  202.  
  203. (*===========================================================================*)
  204. (* Count words in a string                                                   *)
  205. (*    Contrary to the declartion, instr is not VAR.  Thats just to produce   *)
  206. (*    nicer code                                                             *)
  207. (*===========================================================================*)
  208.  
  209. FUNCTION words(VAR instr : STRING) : BYTE;
  210.  
  211.   VAR
  212.     chr_ptr    : BYTE;
  213.     len        : BYTE;
  214.     word_cnt   : BYTE;
  215.  
  216.   BEGIN;
  217.  
  218.     chr_ptr  := 0;
  219.     word_cnt := 0;
  220.     len      := LENGTH(instr);
  221.  
  222.     WHILE chr_ptr < len DO
  223.       BEGIN;
  224.  
  225.         WHILE (chr_ptr < len) AND (instr[chr_ptr+1] = ' ') DO
  226.           INC(chr_ptr);
  227.  
  228.         IF chr_ptr < len THEN
  229.           INC(word_cnt);
  230.  
  231.         WHILE (chr_ptr < len) AND (instr[chr_ptr+1] <> ' ') DO
  232.           INC(chr_ptr);
  233.  
  234.       END;
  235.  
  236.     words := word_cnt;
  237.  
  238.   END;
  239.  
  240. (*===========================================================================*)
  241. (* Strip blanks off a string.  Leading, trailing, or both                    *)
  242. (*    Contrary to the declartion, instr is not VAR.  Thats just to produce   *)
  243. (*    nicer code                                                             *)
  244. (*===========================================================================*)
  245.  
  246. FUNCTION strip (VAR instr : STRING; st_type : CHAR) : STRING;
  247.   VAR
  248.     start_pos : BYTE;
  249.     end_pos   : INTEGER;
  250.   BEGIN;
  251.  
  252. {$IFDEF DEPTH}
  253. stack_depth;
  254. {$ENDIF}
  255.  
  256.     start_pos := 1;
  257.     end_pos := LENGTH(instr);
  258.  
  259.     IF (st_type = 'B') OR (st_type = 'L') THEN
  260.       WHILE (start_pos <= end_pos) AND (instr[start_pos] = ' ') DO
  261.         INC(start_pos);
  262.  
  263.     IF (st_type = 'B') OR (st_type = 'T') THEN
  264.       WHILE (end_pos >= start_pos) AND (instr[end_pos] = ' ') DO
  265.         end_pos := end_pos - 1;
  266.  
  267.     end_pos := end_pos - start_pos + 1;
  268.  
  269.     IF end_pos > 0 THEN
  270.       strip := COPY(instr, start_pos, end_pos)
  271.     ELSE
  272.       strip := '';
  273.  
  274.   END;
  275.  
  276. (*===========================================================================*)
  277. (* Strip blanks off a string.  Leading, trailing, or both                    *)
  278. (*===========================================================================*)
  279.  
  280. PROCEDURE strip_var (VAR instr : STRING; st_type : CHAR);
  281.   VAR
  282.     start_pos : INTEGER;
  283.     end_pos   : INTEGER;
  284.   BEGIN;
  285.  
  286. {$IFDEF DEPTH}
  287. stack_depth;
  288. {$ENDIF}
  289.  
  290.     start_pos := 1;
  291.     end_pos := LENGTH(instr);
  292.  
  293.     IF (st_type = 'B') OR (st_type = 'L') THEN
  294.       WHILE (start_pos <= end_pos) AND (instr[start_pos] = ' ') DO
  295.         INC(start_pos);
  296.  
  297.     IF (st_type = 'B') OR (st_type = 'T') THEN
  298.       WHILE (end_pos >= start_pos) AND (instr[end_pos] = ' ') DO
  299.         end_pos := end_pos - 1;
  300.  
  301.     end_pos := end_pos - start_pos + 1;
  302.  
  303.     IF (end_pos > 0) AND (start_pos > 1) THEN
  304.       MOVE(instr[start_pos], instr[1], end_pos);
  305.  
  306.     instr[0] := CHR(end_pos);
  307.  
  308.   END;
  309.  
  310. (*===========================================================================*)
  311. (* Strip CRLF off the tail of a string.  Also strip LF from front            *)
  312. (*===========================================================================*)
  313.  
  314. PROCEDURE strip_crlf(VAR instr : STRING);
  315.  
  316.   VAR
  317.     c : CHAR;
  318.     i : BYTE;
  319.     j : BYTE;
  320.  
  321.   BEGIN;
  322.  
  323. {$IFDEF DEPTH}
  324. stack_depth;
  325. {$ENDIF}
  326.  
  327.     i := LENGTH(instr);
  328.     c := instr[i];
  329.     WHILE (i > 0) AND ((c = cr) OR (c = lf) OR (c = ' ')) DO
  330.       BEGIN;
  331.         DEC(i);
  332.         c := instr[i];
  333.       END;
  334.  
  335.     j := 1;
  336.     c := instr[1];
  337.     WHILE (i > 0) AND ((c = cr) OR (c = lf) OR (c = ' ')) DO
  338.       BEGIN;
  339.         DEC(i);
  340.         INC(j);
  341.         c := instr[j];
  342.       END;
  343.  
  344.     IF (i > 0) AND (j <> 1) THEN
  345.       MOVE(instr[j], instr[1], i);
  346.  
  347.     instr[0] := CHR(i);
  348.  
  349.   END;
  350.  
  351. (*===========================================================================*)
  352. (* Left justify a string                                                     *)
  353. (*===========================================================================*)
  354.  
  355. FUNCTION left(instr : STRING; length_chr : BYTE) : STRING;
  356.  
  357.   VAR
  358.     i     : INTEGER;
  359.  
  360.   BEGIN;
  361.  
  362.     i := length_chr - LENGTH(instr);
  363.  
  364.     IF i < 0 THEN
  365.       BEGIN;
  366.         left := COPY(instr, 1, length_chr);
  367.         EXIT;
  368.       END;
  369.  
  370.     IF i = 0 THEN
  371.       BEGIN;
  372.         left := instr;
  373.         EXIT;
  374.       END;
  375.  
  376.     FILLCHAR(instr[LENGTH(instr) + 1], i, ' ');
  377.     instr[0] := CHR(length_chr);
  378.  
  379.     left := instr;
  380.  
  381.   END;
  382.  
  383. (*===========================================================================*)
  384. (* Uppercase a string variable                                               *)
  385. (*===========================================================================*)
  386.  
  387. PROCEDURE upcase_str_var(VAR instr : STRING);
  388.  
  389.   VAR
  390.     i : BYTE;
  391.     j : BYTE;
  392.  
  393.   BEGIN;
  394.  
  395.     i := 0;
  396.     j := LENGTH(instr);
  397.     WHILE i < j DO
  398.       BEGIN;
  399.         INC(i);
  400.         instr[i] := UPCASE(instr[i]);
  401.       END;
  402.   END;
  403.  
  404. (*===========================================================================*)
  405. (* Uppercase a string.                                                       *)
  406. (*===========================================================================*)
  407.  
  408. FUNCTION upcase_str(instr : STRING) : STRING;
  409.  
  410.   BEGIN;
  411.  
  412. {$IFDEF DEPTH}
  413. stack_depth;
  414. {$ENDIF}
  415.  
  416.     upcase_str_var(instr);
  417.     upcase_str := instr;
  418.  
  419.   END;
  420.  
  421. (*===========================================================================*)
  422. (* Find a word in a string                                                   *)
  423. (*    Contrary to the declartion, haystack and needle are not VAR.  Thats    *)
  424. (*    just to save stack space                                               *)
  425. (*===========================================================================*)
  426.  
  427. FUNCTION find(haystack : str_ptr; needle : str_ptr) : BYTE;
  428.  
  429.   VAR
  430.     i          : WORD;
  431.     j          : WORD;
  432.     k          : WORD;
  433.     l_haystack : BYTE;
  434.     l_needle   : BYTE;
  435.     w          : BYTE;
  436.  
  437.   BEGIN;
  438.  
  439. {$IFDEF DEPTH}
  440. stack_depth;
  441. {$ENDIF}
  442.  
  443.     i          := 1;
  444.     l_haystack := LENGTH(haystack^);
  445.     l_needle   := LENGTH(needle^);
  446.     w          := 0;
  447.     find       := 0;
  448.  
  449.     WHILE i <= l_haystack DO
  450.       BEGIN;
  451.  
  452.         INC(w);
  453.  
  454.         WHILE (i <= l_haystack) AND (haystack^[i] = ' ') DO
  455.           INC(i);
  456.  
  457.         IF i > l_haystack THEN EXIT;
  458.  
  459.         j := i + l_needle - 1;
  460.  
  461.         IF j > l_haystack THEN EXIT;
  462.  
  463.         IF ((j < l_haystack) AND (haystack^[j + 1] = ' '))
  464.                                             OR (j = l_haystack) THEN
  465.           BEGIN;
  466.  
  467.             k := 1;
  468.             WHILE (k <= l_needle) AND (haystack^[i] = needle^[k]) DO
  469.               BEGIN;
  470.                 INC(k);
  471.                 INC(i);
  472.               END;
  473.  
  474.             IF k > l_needle THEN
  475.               BEGIN;
  476.                 find := w;
  477.                 EXIT;
  478.               END;
  479.  
  480.           END;
  481.  
  482.         WHILE (i <= l_haystack) AND (haystack^[i] <> ' ') DO
  483.           INC(i);
  484.  
  485.       END;
  486.  
  487.   END;
  488.  
  489. FUNCTION  substr_compare (VAR instr      : STRING;
  490.                               start_chr  : BYTE;
  491.                               compare_str: STRING)  : BOOLEAN;
  492.   VAR
  493.     i : BYTE;
  494.   BEGIN;
  495.  
  496.     substr_compare := FALSE;
  497.  
  498.     IF (start_chr + LENGTH(compare_str) - 1) > LENGTH(instr) THEN
  499.       EXIT;
  500.  
  501.     i := 0;
  502.     WHILE (i < LENGTH(compare_str)) DO
  503.       BEGIN;
  504.         IF instr[i + start_chr] <> compare_str[i + 1] THEN EXIT;
  505.         INC(i);
  506.       END;
  507.  
  508.     substr_compare := TRUE;
  509.  
  510.   END;
  511.  
  512. END.
  513.